package com.hgsoft.yfzx.component.filehelper.util;

import org.apache.commons.io.FileUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * HttpClient 远程请求类
 *
 * @author RuiHaoZ on GuangZhou
 * @date 2018/10/11 20:53
 */
public class HttpClientUtil {

    private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
    private static String CHARSET = "utf-8";
    private static ContentType UTF8 = ContentType.create("text/plain", Consts.UTF_8);

    /**
     * 发送POST请求
     *
     * @param url         请求地址
     * @param map         参数
     * @param accessToken 密码
     * @return
     */
    public static String sendPost(String url, Map<String, String> map, String accessToken) throws IOException {
        StringUtil.convertMapToUrlString(map);
        String response = "";
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> nvps = new ArrayList<>();
        map.forEach((k, v) -> nvps.add(new BasicNameValuePair(k, v)));
        httpPost.setEntity(new UrlEncodedFormEntity(nvps, CHARSET));
        return sendAndGetEntityString(httpPost, accessToken);
    }

    /**
     * 发送POST请求
     *
     * @param url         请求地址
     * @param map         请求参数
     * @param accessToken 密码
     * @param files       请求文件
     * @return
     */
    public static String sendPost(String url, Map<String, String> map, String accessToken,
                                  Map<String, File> files) throws IOException {
        // 把一个普通参数和文件上传给下面这个地址 是一个servlet
        HttpPost httpPost = new HttpPost(url);
        // 把文件转换成流对象FileBody
        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
        entityBuilder.setCharset(Consts.UTF_8);
        files.forEach((k, v) -> entityBuilder.addPart("file", new FileBody(v, UTF8)));
        map.forEach((k, v) -> entityBuilder.addPart(k, new StringBody(v, UTF8)));
        HttpEntity reqEntity = entityBuilder.build();
        httpPost.setEntity(reqEntity);
        return sendAndGetEntityString(httpPost, accessToken);
    }

    /**
     * 发送PUT请求
     *
     * @param url         请求地址
     * @param map         参数
     * @param accessToken 密码
     * @return
     */
    public static String sendPut(String url, Map<String, String> map, String accessToken) throws Exception{
        StringUtil.convertMapToUrlString(map);
        String response = "";
        HttpPut httpPut = new HttpPut(url);
        List<NameValuePair> nvps = new ArrayList<>();
        map.forEach((k, v) -> nvps.add(new BasicNameValuePair(k, v)));
        httpPut.setEntity(new UrlEncodedFormEntity(nvps, CHARSET));
        return sendAndGetEntityString(httpPut, accessToken);
    }

    /**
     * 发送GET请求
     *
     * @param url         请求地址
     * @param map         请求参数
     * @param accessToken 密码
     * @return
     */
    public static String sendGet(String url, Map<String, String> map, String accessToken) throws IOException {
        String response = "";
        String params = StringUtil.convertMapToUrlString(map);
        HttpGet httpGet = new HttpGet(url + "?" + params);
        return sendAndGetEntityString(httpGet, accessToken);
    }

    /**
     * 发送DELETE请求
     *
     * @param url         请求地址
     * @param map         请求参数
     * @param accessToken 密码
     * @return
     */
    public static String sendDelete(String url, Map<String, String> map, String accessToken) throws IOException {
        String response = "";
        String params = StringUtil.convertMapToUrlString(map);
        HttpDelete httpDelete = new HttpDelete(url + "?" + params);
        return sendAndGetEntityString(httpDelete, accessToken);
    }

    /**
     * 发送BASE_GET请求
     *
     * @param url     请求地址
     * @param map     请求参数
     * @param headers 请求头部信息
     * @return
     */
    public static String sendBaseGet(String url, Map<String, String> map, Map<String, String> headers) throws IOException {
        String response = "";
        String params = StringUtil.convertMapToUrlString(map);
        HttpGet httpGet = new HttpGet(url + "?" + params);
        for (Map.Entry<String, String> e : headers.entrySet()) {
            httpGet.addHeader(e.getKey(), e.getValue());
        }
        return sendAndGetEntityString(httpGet, "");
    }

    public static String sendAndGet(String url, Map<String, String> map, String accessToken) throws IOException {

        //1、创建实例
        CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
        String params = StringUtil.convertMapToUrlString(map);
        //2、创建请求
        HttpGet httpGet = new HttpGet(url + "?" + params);
        //3、执行
        CloseableHttpResponse closeableHttpResponse = closeableHttpClient.execute(httpGet);
        //4、获取实体
        HttpEntity httpEntity = closeableHttpResponse.getEntity();
        if (httpEntity != null) {
            System.out.println("ContentType:" + httpEntity.getContentType().getValue());
            InputStream inputStream = httpEntity.getContent();
            //将图片保存在本次磁盘D盘，命名为xxx.png
            FileUtils.copyToFile(inputStream, new File("D://xxx.png"));
        }
        closeableHttpResponse.close();
        closeableHttpClient.close();
        return "";
    }

    /**
     * 请求服务主进程
     *
     * @param httpBase    请求方式
     * @param accessToken 密码
     * @return
     * @throws IOException
     */
    private static String sendAndGetEntityString(
            HttpRequestBase httpBase, String accessToken) throws IOException {

        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        httpBase.setHeader("JSONWebTokens", accessToken);
        httpBase.setHeader("fromWhere", "IMAGE_CLIENT");

        logger.info("请求详情：[{}]", httpBase.toString());
        CloseableHttpResponse httpResponse = httpClient.execute(httpBase);
        HttpEntity resEntity = httpResponse.getEntity();
        String response = resEntity != null ? EntityUtils.toString(resEntity) : "";
        String respCode = String.valueOf(httpResponse.getStatusLine().getStatusCode());
        logger.info("请求返回[{}]:{}", respCode, response);
        if (!"200".equals(respCode)) {
            return respCode;
        }
        EntityUtils.consume(resEntity);
        return response;
    }
}
